import os

import requests
from loguru import logger

from mdtool.entity.fs_entity import BitTable


class BitBot:
    def __init__(self, access_token):
        self.access_token = access_token

    def create_bitTable(self, folderToken: str, name: str):
        url = "https://open.feishu.cn/open-apis/bitable/v1/apps"
        headers = {
            "Authorization": f"Bearer {self.access_token}",
            "Content-Type": "application/json; charset=utf-8",
        }
        data = {"folder_token": folderToken, "name": name}
        resp = requests.post(url, headers=headers, json=data)
        ret = resp.json()
        if ret["code"] != 0:
            logger.warning(f"无法创建多维表格：{name}")
            return BitTable.EMPTY
        return BitTable.fromJson(ret["data"]["app"])


class FsRobot:
    """从环境变量 FEISHU_APP_ID 和 FEISHU_APP_SECRET 中读取 app_id 和 app_secret"""

    def __init__(self):
        self.config = {}
        self.config["APP_ID"] = os.getenv("FEISHU_APP_ID")
        self.config["APP_SECRET"] = os.getenv("FEISHU_APP_SECRET")

    # 获取访问令牌
    def _get_tenant_access_token(self):
        url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal"
        headers = {"Content-Type": "application/json; charset=utf-8"}
        data = {
            "app_id": self.config["APP_ID"],
            "app_secret": self.config["APP_SECRET"],
        }
        response = requests.post(url, headers=headers, json=data)
        if response.status_code == 200:
            result = response.json()
            if result.get("code") == 0:
                return result.get("tenant_access_token")
        return result

    # 向飞书表格写入数据
    def write_data_to_sheet(self, spreadsheet_token, sheet_id, data_range, values):
        url = f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values_batch_update"
        headers = {
            "Authorization": f"Bearer {self._get_tenant_access_token()}",
            "Content-Type": "application/json; charset=utf-8",
        }
        data = {
            "valueRanges": [
                {
                    "range": f"{sheet_id}!{data_range}",
                    "values": values,
                }  # 从 A1 单元格开始写入
            ]
        }
        response = requests.post(url, headers=headers, json=data)
        return response.json()

    def add_sheet(self, spreadsheet_token, sheet_title: str = "Sheet1", index=1):
        url = f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/sheets_batch_update"
        headers = {
            "Authorization": f"Bearer {self._get_tenant_access_token()}",
            "Content-Type": "application/json; charset=utf-8",
        }
        data = {
            "requests": [
                {"addSheet": {"properties": {"title": sheet_title, "index": index}}}
            ]
        }
        response = requests.post(url, headers=headers, json=data)
        return response.json()

    def delete_spreadsheet(self, title):
        url = "https://open.feishu.cn/open-apis/sheets/v3/spreadsheets"
        headers = {
            "Authorization": f"Bearer {self._get_tenant_access_token()}",
            "Content-Type": "application/json; charset=utf-8",
        }
        data = {"title": title}
        resp = requests.post(url, headers=headers, json=data)
        return resp.json()

    def create_spreadsheet(self, title):
        url = "https://open.feishu.cn/open-apis/sheets/v3/spreadsheets"
        headers = {
            "Authorization": f"Bearer {self._get_tenant_access_token()}",
            "Content-Type": "application/json; charset=utf-8",
        }
        data = {"title": title}
        resp = requests.post(url, headers=headers, json=data)
        return resp.json()

    # 获取指定电子表格的所有工作表信息

    def get_sheet_info(self, spreadsheet_token):
        url = f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{self._get_tenant_access_token()}/sheets/query"
        headers = {
            "Authorization": f"Bearer {self._get_tenant_access_token()}",
            "Content-Type": "application/json; charset=utf-8",
        }
        response = requests.get(url, headers=headers)
        return response.json()

    def get_all_files_under_folder_token(self, folder_token):
        url = f"https://open.feishu.cn/open-apis/drive/v1/files?folder_token={folder_token}&order_by=EditedTime"
        headers = {
            "Authorization": f"Bearer {self._get_tenant_access_token()}",
            "Content-Type": "application/json; charset=utf-8",
        }
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
            return response.json()

    def get_root_folder_token(self):
        return self.__get_document_root_folder()

    # 获取云文档的根目录
    def __get_document_root_folder(self):
        url = "https://open.feishu.cn/open-apis/drive/explorer/v2/root_folder/meta"
        headers = {
            "Authorization": f"Bearer {self._get_tenant_access_token()}",
            "Content-Type": "application/json; charset=utf-8",
        }
        response = requests.get(url, headers=headers)
        return response.json()

    def find_document_by_file_title(self, title):
        return self.__find_file_by_attr("name", title)

    def find_document_by_file_token(self, token):
        return self.__find_file_by_attr("token", token)

    def __find_file_by_attr(self, attr, value):
        files = self.get_all_files_under_folder_token(self.get_root_folder_token())

        for file in files:
            ret = file[attr]
            if ret == value:
                return file
        return None

    def get_sheet_ids_by_file_token(self, file_token, sheet_index=0):
        file = self.find_document_by_file_token(file_token)
        file_token = file["token"]
        url = f"https://open.feishu.cn/open-apis/sheets/v3/spreadsheets/{file_token}/sheets/query"
        headers = {
            "Authorization": f"Bearer {self._get_tenant_access_token()}",
            "Content-Type": "application/json; charset=utf-8",
        }
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
            ret = response.json()
            if ret["code"] == 0:
                return ret["data"]["sheets"][sheet_index]["sheet_id"]
            else:
                return ""

    def read_data_from_sheet(self, spreadsheet_token, sheet_id, data_range):
        """
        读取飞书表格指定 sheet_id 和 range 的所有数据。
        :param spreadsheet_token: 表格 token
        :param sheet_id: 工作表 id
        :param data_range: 读取范围（如 'A1' 或 'A1:B10'）
        :return: 读取到的数据（二维数组）
        """
        url = f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values/{sheet_id}!{data_range}"
        headers = {
            "Authorization": f"Bearer {self._get_tenant_access_token()}",
            "Content-Type": "application/json; charset=utf-8",
        }
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
            result = response.json()
            if result.get("code") == 0:
                return result["data"].get("valueRange", {}).get("values", [])
            else:
                logger.error(f"读取飞书表格数据失败: {result}")
                return []
        else:
            logger.error(f"HTTP请求失败，状态码: {response.status_code}")
            return []

    def get_spreadsheet_token_and_sheet_id_by_name(self, spreadsheet_name, sheet_name):
        """
        根据 spreadsheet 名称和 sheet 名称，返回 spreadsheet 的 token 和 sheet_id。
        :param spreadsheet_name: 表格名称
        :param sheet_name: 工作表名称
        :return: (spreadsheet_token, sheet_id) 或 (None, None) 如果未找到
        """
        spreadsheet = self.find_document_by_file_title(spreadsheet_name)
        if not spreadsheet:
            logger.error(f"未找到名为 {spreadsheet_name} 的 spreadsheet")
            return None, None
        spreadsheet_token = spreadsheet["token"]
        url = f"https://open.feishu.cn/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/query"
        headers = {
            "Authorization": f"Bearer {self._get_tenant_access_token()}",
            "Content-Type": "application/json; charset=utf-8",
        }
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
            result = response.json()
            if result.get("code") == 0:
                for sheet in result["data"]["sheets"]:
                    if sheet["title"] == sheet_name:
                        return spreadsheet_token, sheet["sheet_id"]
                logger.error(f"未找到名为 {sheet_name} 的 sheet")
                return spreadsheet_token, None
            else:
                logger.error(f"获取 sheet 列表失败: {result}")
                return spreadsheet_token, None
        else:
            logger.error(f"HTTP请求失败，状态码: {response.status_code}")
            return spreadsheet_token, None

    def delete_rows(self, spreadsheet_token, sheet_id, row_nums):
        if not row_nums:
            logger.info("没有需要删除的行。")
            return {"code": 0, "msg": "没有需要删除的行"}
        # 从大行号开始逐行删除
        sorted_lines = sorted(row_nums, reverse=True)

        url = f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/dimension_range"
        headers = {
            "Authorization": f"Bearer {self._get_tenant_access_token()}",
            "Content-Type": "application/json; charset=utf-8",
        }
        undeleted = []
        for row_no in sorted_lines:
            payload = {
                "dimension": {
                    "sheetId": sheet_id,
                    "majorDimension": "ROWS",
                    "startIndex": row_no,
                    "endIndex": row_no,
                }
            }
            response = requests.delete(url, headers=headers, json=payload)
            try:
                ret = response.json()
                logger.debug(f"已删除第 {row_no} 行: {ret}")
            except Exception as e:
                logger.error(f"解析返回内容失败: {e}, 原始内容: {response.text}")
                undeleted.append(row_no)
        return undeleted


if __name__ == "__main__":

    fsrobot = FsRobot()
    root = fsrobot.get_root_folder_token()
    print(root)
    # bitbot = BitBot(fsrobot._FsRobot__get_access_token())
    # ret = bitbot.create_bitTable(root, "my_first_bit")
    # print(ret)
